/*////////////////////////////////////////////////////////////////////
// The Original Code is the "LastTab" extension for Mozilla Firefox.//
// version 1.5 - October 26, 2005                                  //
// The Initial Developer of the Original Code is Timothy Humphrey. //
*////////////////////////////////////////////////////////////////////
var TMP_LastTab = {
   CtrlKey : false,
   favorLeftToRightOrdering : true,
   handleCtrlTab : true,
   KeyboardNavigating : true,
   KeyLock : false,
   respondToMouseInTabList : true,
   showTabList : true,
   SuppressTabListReset : false,
   TabBar : null,
   TabBox : null,
   TabHistory : [],
   TabIndex : 0,
   TabList : null,
   TabListLock : false,

   DisplayTabList : function() {
      var element = document.documentElement;
      var tablist = TMP_LastTab.TabList;
      var menuitem, tab, imageUrl, x, y, i, activeIndex;

      createCommonList(tablist, this.handleCtrlTab ? 3 : 2);

      var item = tablist.childNodes[TMP_LastTab.TabIndexToMenuItem()];
      item.setAttribute("_moz-menuactive", "true");
      updateMenuItemActive(null, item);

      //moveTo() method introduces anomalies, e.g. hovering over location bar moves the popup; hiding	and showing the popup works better
      document.popupNode = element;
      x = -element.boxObject.screenX;
      y = 10000;
      tablist.showPopup(element, x, y, "popup", null, null); //show offscreen to get popup measurements
      x = Math.round((window.outerWidth - tablist.boxObject.width) / 2) - (element.boxObject.screenX - window.screenX);
      y = Math.round((window.outerHeight - tablist.boxObject.height) / 2) - (element.boxObject.screenY - window.screenY);
      if(x + element.boxObject.screenX < 0)
         x = -element.boxObject.screenX;
      else if(x + element.boxObject.screenX + tablist.boxObject.width > window.screen.availWidth)
         x = window.screen.availWidth - tablist.boxObject.width - element.boxObject.screenX;
      if(y + element.boxObject.screenY < 0)
         y = -element.boxObject.screenY;
      else if(y + element.boxObject.screenY + tablist.boxObject.height > window.screen.availHeight)
         y = window.screen.availHeight - tablist.boxObject.height - element.boxObject.screenY;
      if(x == -1 && y == -1) //workaround special status of -1, -1 position in showPopup() method
         x = y = 0;
      TMP_LastTab.SuppressTabListReset = true;
      tablist.hidePopup();
      TMP_LastTab.SuppressTabListReset = false;
      tablist.showPopup(element, x, y, "popup", null, null);

      var ietab = "chrome://ietab/content/reloaded.html?url="
      if (gBrowser.currentURI.spec.indexOf(ietab) == 0)
         tablist.focus();

      TMP_LastTab.TabListLock = true;
   },

   init : function() {
      var browser = document.documentElement;

      TMP_LastTab.TabBox = getBrowser().mTabBox;
      TMP_LastTab.TabBar = getBrowser().mTabContainer;
      TMP_LastTab.TabList = document.getElementById("lasttabTabList");

      TMP_LastTab.TabBox._eventNode.removeEventListener("keypress", TMP_LastTab.TabBox._keyEventHandler, true);
      browser.addEventListener("keydown", TMP_LastTab.OnKeyDown, true);
      browser.addEventListener("keypress", TMP_LastTab.OnKeyPress, true);
      browser.addEventListener("keyup", TMP_LastTab.OnKeyUp, true);
      TMP_LastTab.TabList.addEventListener("DOMMenuItemActive", TMP_LastTab.ItemActive, true);
      TMP_LastTab.TabList.addEventListener("DOMMenuItemInactive", TMP_LastTab.ItemInactive, true);

      TMP_LastTab.TabBar.childNodes[0].__LastTab = true;
      TMP_LastTab.TabHistory.push(TMP_LastTab.TabBar.childNodes[0]);

      // we change pref string in tabtreemix 0.3
      if (tabxPrefs.prefHasUserValue("HandleCtrlTab")) {
         tabxPrefs.setBoolPref("lasttab.handleCtrlTab", tabxPrefs.getBoolPref("HandleCtrlTab"));
         tabxPrefs.clearUserPref("HandleCtrlTab");
      }
      if (tabxPrefs.prefHasUserValue("CtrlTabLeftToRight")) {
         tabxPrefs.clearUserPref("CtrlTabLeftToRight");
      }

      TMP_LastTab.ReadPreferences();
   },
   
   deinit : function() {
      var browser = document.documentElement;
      browser.removeEventListener("keydown", TMP_LastTab.OnKeyDown, true);
      browser.removeEventListener("keypress", TMP_LastTab.OnKeyPress, true);
      browser.removeEventListener("keyup", TMP_LastTab.OnKeyUp, true);
      TMP_LastTab.TabList.removeEventListener("DOMMenuItemActive", TMP_LastTab.ItemActive, true);
      TMP_LastTab.TabList.removeEventListener("DOMMenuItemInactive", TMP_LastTab.ItemInactive, true);
   },
   
   ItemActive : function(event) {
      updateMenuItemActive(event);
      if(TMP_LastTab.respondToMouseInTabList) {
         if(TMP_LastTab.KeyboardNavigating) {
            if(event.target.value != TMP_LastTab.inverseIndex(TMP_LastTab.TabIndex))
               TMP_LastTab.TabList.childNodes[TMP_LastTab.TabIndexToMenuItem()].setAttribute("_moz-menuactive", "false");
            TMP_LastTab.KeyboardNavigating = false;
         }
         TMP_LastTab.TabIndex = TMP_LastTab.inverseIndex(event.target.value);
      }
      else {
         if(event.target.value != TMP_LastTab.inverseIndex(TMP_LastTab.TabIndex))
            event.target.setAttribute("_moz-menuactive", "false");
      }
   },

   ItemInactive : function(event) {
      updateMenuItemInactive(event);
      if(!TMP_LastTab.respondToMouseInTabList && event.target.value == TMP_LastTab.inverseIndex(TMP_LastTab.TabIndex))
         event.target.setAttribute("_moz-menuactive", "true");
   },

   MaintainTabHistory : function() {
      var newTabs = [];
      var tab, tabCount;
      var i;

      // Gather tab synchronization info
      tabCount = TMP_LastTab.TabBar.childNodes.length;
      for(i = 0; i < tabCount; i++) {
         tab = TMP_LastTab.TabBar.childNodes[i];
         if(!tab.__LastTab)
            newTabs[newTabs.length] = tab;
      }

      // Purge old tab info from history
      i = 0;
try{
      while(i < TMP_LastTab.TabHistory.length) {
         if(!TMP_LastTab.TabHistory[i] || TMP_LastTab.TabHistory[i].parentNode != TMP_LastTab.TabBar)
            TMP_LastTab.TabHistory.splice(i, 1);
         else
            i++;
      }
} catch (e) {tmLog("error from Ctrl+Tab in MaintainTabHistory " + typeof(TMP_LastTab.TabHistory[i]) + "\n" + e
+ "\n" + "TMP_LastTab.TabHistory.length " + TMP_LastTab.TabHistory.length + "\n" + "i " + i);}

      // Add new tabs to history
      if(newTabs.length > 0) {
         tab = TMP_LastTab.TabHistory.pop();
         if(TMP_LastTab.favorLeftToRightOrdering) {
            for(i = newTabs.length - 1; i >= 0; i--) {
               newTabs[i].__LastTab = true;
               TMP_LastTab.TabHistory.push(newTabs[i]);
            }
         }
         else {
            for(i = 0; i < newTabs.length; i++) {
               newTabs[i].__LastTab = true;
               TMP_LastTab.TabHistory.push(newTabs[i]);
            }
         }
         TMP_LastTab.TabHistory.push(tab);
      }
   },

   OnKeyDown : function(event) {
      TMP_LastTab.CtrlKey = event.ctrlKey && !event.altKey && !event.metaKey;
   },

   OnKeyPress : function(event) {
      var tabCount = TMP_LastTab.handleCtrlTab ? TMP_LastTab.TabHistory.length : gBrowser.mTabs.length;

      if((TMP_LastTab.handleCtrlTab || TMP_LastTab.showTabList) && event.keyCode == event.DOM_VK_TAB && event.ctrlKey && !event.altKey && !event.metaKey) {
         if(!TMP_LastTab.KeyLock) {
            if (TMP_LastTab.handleCtrlTab) {
               TMP_LastTab.MaintainTabHistory();
               tabCount = TMP_LastTab.TabHistory.length;
               TMP_LastTab.TabIndex = tabCount - 1;
            } else {
               TMP_LastTab.TabIndex = tabCount - 1 - gBrowser.mCurrentTab._tPos;
            }
            TMP_LastTab.KeyLock = true;
         }

         if(TMP_LastTab.TabListLock)
            TMP_LastTab.TabList.childNodes[TMP_LastTab.TabIndexToMenuItem()].setAttribute("_moz-menuactive", "false");

         if(event.shiftKey) {
            TMP_LastTab.TabIndex++;
            if(TMP_LastTab.TabIndex >= tabCount)
               TMP_LastTab.TabIndex = 0;
         }
         else {
            TMP_LastTab.TabIndex--;
            if(TMP_LastTab.TabIndex < 0)
               TMP_LastTab.TabIndex = tabCount - 1;
         }

         if(TMP_LastTab.showTabList) {
            TMP_LastTab.KeyboardNavigating = true;
            if(!TMP_LastTab.TabListLock) {
               if(tabCount > 1)
                  TMP_LastTab.DisplayTabList();
            }
            else {
               var item = TMP_LastTab.TabList.childNodes[TMP_LastTab.TabIndexToMenuItem()];
               item.setAttribute("_moz-menuactive", "true");
               updateMenuItemActive(null, item);
            }               
         }
         else {
            TMP_LastTab.TabBox.selectedTab = TMP_LastTab.TabHistory[TMP_LastTab.TabIndex];
            TMP_LastTab.TabBar.ensureTabIsVisible(TMP_LastTab.TabBox.selectedTab._tPos);
         }
         
         event.stopPropagation();
         event.preventDefault();
      }
      else {
         if(TMP_LastTab.TabListLock)
            TMP_LastTab.TabList.hidePopup();

         TMP_LastTab.TabBox._keyEventHandler.handleEvent(event);
      }
   },

   OnKeyUp : function(event) {
      var keyReleased = event.keyCode == event.DOM_VK_CONTROL;

      TMP_LastTab.CtrlKey = event.ctrlKey && !event.altKey && !event.metaKey;
      if(keyReleased && TMP_LastTab.TabListLock) {
         if(TMP_LastTab.TabList.childNodes[TMP_LastTab.TabIndexToMenuItem()].getAttribute("_moz-menuactive") == "true") {
            TMP_LastTab.TabBox.selectedTab = TMP_LastTab.handleCtrlTab ? TMP_LastTab.TabHistory[TMP_LastTab.TabIndex] : gBrowser.mTabs[gBrowser.mTabs.length - 1 - TMP_LastTab.TabIndex];
            TMP_LastTab.TabBar.ensureTabIsVisible(TMP_LastTab.TabBox.selectedTab._tPos);
         }

         updateMenuItemInactive(null);
         gBackupLabel=="";

         TMP_LastTab.PushSelectedTab();
         TMP_LastTab.TabList.hidePopup();
      }
      if(keyReleased && TMP_LastTab.KeyLock) {
         TMP_LastTab.PushSelectedTab();
         TMP_LastTab.TabIndex = 0;
         TMP_LastTab.KeyLock = false;
      }
   },

   OnMenuCommand : function(event) {
      if(TMP_LastTab.respondToMouseInTabList) {
         TMP_LastTab.TabBox.selectedTab = TMP_LastTab.handleCtrlTab ? TMP_LastTab.TabHistory[event.target.value] : gBrowser.mTabs[event.target.value];
         TMP_LastTab.TabBar.ensureTabIsVisible(TMP_LastTab.TabBox.selectedTab._tPos);
         TMP_LastTab.PushSelectedTab();
      }
   },

   OnPopupHidden : function() {
      if(!TMP_LastTab.SuppressTabListReset) {
         var tablist = TMP_LastTab.TabList;

         while(tablist.childNodes.length > 0)
            tablist.removeChild(tablist.childNodes[0]);

         TMP_LastTab.TabListLock = false;
         TMP_LastTab.TabIndex = 0;
         TMP_LastTab.KeyLock = false;

         hideCommonList(tablist);
      }
   },

   OnSelect : function(event) {
      var tabCount = TMP_LastTab.TabHistory.length;

      TMP_LastTab.MaintainTabHistory();
      if(tabCount != TMP_LastTab.TabBar.childNodes.length) {
         if(tabCount > TMP_LastTab.TabBar.childNodes.length) {
            if(TMP_LastTab.TabBar.childNodes.length == 1) {
               TMP_LastTab.KeyLock = false;
               TMP_LastTab.TabIndex = 0;
            }
         }
         TMP_LastTab.PushSelectedTab();
      }
      else if(!TMP_LastTab.KeyLock) {
         if(TMP_LastTab.CtrlKey)
            TMP_LastTab.KeyLock = true; //allow other tab navigation methods to work
         else
            TMP_LastTab.PushSelectedTab();
      }
   },

   PushSelectedTab : function() {
      var selectedTab = TMP_LastTab.TabBar.selectedItem;
      var tabCount, i;

      if(TMP_LastTab.TabHistory[TMP_LastTab.TabHistory.length - 1] != selectedTab) {
         tabCount = TMP_LastTab.TabHistory.length;
         for(i = 0; i < tabCount; i++) {
            if(TMP_LastTab.TabHistory[i] == selectedTab) {
               TMP_LastTab.TabHistory.push(TMP_LastTab.TabHistory.splice(i, 1)[0]);
               break;
            }
         }
      }
   },

   ReadPreferences : function() {
      TMP_LastTab.handleCtrlTab = tabxPrefs.getBoolPref("lasttab.handleCtrlTab");
      TMP_LastTab.favorLeftToRightOrdering = tabxPrefs.getBoolPref("lasttab.favorLeftToRightOrdering");
      TMP_LastTab.respondToMouseInTabList = tabxPrefs.getBoolPref("lasttab.respondToMouseInTabList");
      TMP_LastTab.showTabList = tabxPrefs.getBoolPref("lasttab.showTabList");
   },

   TabIndexToMenuItem : function() {
      var activeIndex;
      if (TMP_LastTab.handleCtrlTab)
         activeIndex = TMP_LastTab.TabHistory.length - 1 - TMP_LastTab.TabIndex;
      else
         activeIndex = gBrowser.mTabs.length - 1 - TMP_LastTab.TabIndex;
      return activeIndex;
   },

   inverseIndex : function(index) {
      return TMP_LastTab.handleCtrlTab ? index : gBrowser.mTabs.length - 1 - index;
   }

};
